package com.example.netty;

import java.nio.charset.Charset;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.string.StringEncoder;
 
public class NettyServer {
	
	private static final Logger log = LoggerFactory.getLogger(NettyServer.class);

 
    public void bind(int port) throws Exception {
    	
    	log.info("netty start at port:{},begin",port);
 
        EventLoopGroup bossGroup = new NioEventLoopGroup(); //bossGroup就是parentGroup，是负责处理TCP/IP连接的
        EventLoopGroup workerGroup = new NioEventLoopGroup(); //workerGroup就是childGroup,是负责处理Channel(通道)的I/O事件
 
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 128) //初始化服务端可连接队列,指定了队列的大小128
            .childOption(ChannelOption.SO_KEEPALIVE, true) //保持长连接
            .childHandler(new ChannelInitializer<SocketChannel>() { // 绑定客户端连接时候触发操作

				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					System.out.println("报告");
					System.out.println("信息：有一客户端链接到本服务端");
					System.out.println("IP:" + ch.localAddress().getHostName());
					System.out.println("Port:" + ch.localAddress().getPort());
					System.out.println("报告完毕");

					ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
					ch.pipeline().addLast(new MyCustomHandler()); // 客户端触发操作
					ch.pipeline().addLast(new ByteArrayEncoder());
				}
			});
        //绑定监听端口，调用sync同步阻塞方法等待绑定操作完
        ChannelFuture future = sb.bind(port).sync();
 
        if (future.isSuccess()) {
        	log.info("netty start at port:{},success",port);

        } else {
        	log.info("netty start at port:{},failed",port);

            future.cause().printStackTrace();
            bossGroup.shutdownGracefully(); //关闭线程组
            workerGroup.shutdownGracefully();
        }
 
        //成功绑定到端口之后,给channel增加一个 管道关闭的监听器并同步阻塞,直到channel关闭,线程才会往下执行,结束进程。
        future.channel().closeFuture().sync();
 
    }

}
